Skip to content

Add configure_logging opt-out to MCPServer (#1656)#3071

Open
gee-46 wants to merge 2 commits into
modelcontextprotocol:mainfrom
gee-46:fix/1656-configure-logging-opt-out
Open

Add configure_logging opt-out to MCPServer (#1656)#3071
gee-46 wants to merge 2 commits into
modelcontextprotocol:mainfrom
gee-46:fix/1656-configure-logging-opt-out

Conversation

@gee-46

@gee-46 gee-46 commented Jul 7, 2026

Copy link
Copy Markdown

Fixes #1656

MCPServer.__init__ unconditionally calls logging.basicConfig().
This is fine for quick scripts, but for applications that embed
MCPServer as a library, it means:

  • If the app hasn't configured its own logging yet when the server is
    created, the server's config wins the race, and any later
    logging.basicConfig() call by the app becomes a silent no-op
    (per stdlib's own basicConfig contract).

This adds configure_logging: bool = True to MCPServer.__init__.
Default behavior is fully unchanged; embedding applications can pass
configure_logging=False to keep complete control of their own
logging setup.

Added tests covering both the default (no regression) and the new
opt-out behavior.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/server/mcpserver/test_configure_logging.py">

<violation number="1" location="tests/server/mcpserver/test_configure_logging.py:35">
P2: The new opt-out test can pass even if `configure_logging=False` is ignored when pytest has already attached root handlers. Because `logging.basicConfig()` is a no-op with existing handlers, constructing `MCPServer` against the `baseline` handler list does not exercise the race this option fixes; clearing the root handlers before constructing the server (or spying on `_configure_logging`) would make the regression test cover the intended no-handlers case.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

This matches the standard library's own `logging.basicConfig()`
contract: it is a no-op if the root logger already has handlers.
"""
baseline = list(clean_root_logger.handlers)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new opt-out test can pass even if configure_logging=False is ignored when pytest has already attached root handlers. Because logging.basicConfig() is a no-op with existing handlers, constructing MCPServer against the baseline handler list does not exercise the race this option fixes; clearing the root handlers before constructing the server (or spying on _configure_logging) would make the regression test cover the intended no-handlers case.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/server/mcpserver/test_configure_logging.py, line 35:

<comment>The new opt-out test can pass even if `configure_logging=False` is ignored when pytest has already attached root handlers. Because `logging.basicConfig()` is a no-op with existing handlers, constructing `MCPServer` against the `baseline` handler list does not exercise the race this option fixes; clearing the root handlers before constructing the server (or spying on `_configure_logging`) would make the regression test cover the intended no-handlers case.</comment>

<file context>
@@ -0,0 +1,62 @@
+        This matches the standard library's own `logging.basicConfig()`
+        contract: it is a no-op if the root logger already has handlers.
+        """
+        baseline = list(clean_root_logger.handlers)
+        app_handler = logging.StreamHandler()
+        clean_root_logger.addHandler(app_handler)
</file context>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks — you're right that comparing root logger state was
fragile since pytest's own log capture handler masks the exact race
this fixes. Pushed a fix that spies on _configure_logging directly
instead, and verified it actually fails if the configure_logging flag
is ignored (I temporarily reverted the fix locally to confirm).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FastMCP configures logging on init, which messes up application-level logging

1 participant